package com.mall.b2c.service.impl;

import javax.annotation.Resource;
import javax.persistence.LockModeType;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.mall.b2c.dao.OrderDao;
import com.mall.b2c.dao.OrderItemDao;
import com.mall.b2c.dao.ShippingDao;
import com.mall.b2c.domain.delivery.DeliveryCenterDomain;
import com.mall.b2c.domain.delivery.DeliveryMethodDomain;
import com.mall.b2c.domain.order.OrderDomain;
import com.mall.b2c.domain.order.OrderItemDomain;
import com.mall.b2c.domain.order.OrderLogDomain;
import com.mall.b2c.domain.order.ShippingDomain;
import com.mall.b2c.domain.order.ShippingItemDomain;
import com.mall.b2c.enums.LogType;
import com.mall.b2c.enums.OrderStatus;
import com.mall.b2c.enums.ShipStatus;
import com.mall.b2c.service.DeliveryCenterService;
import com.mall.b2c.service.DeliveryMethodService;
import com.mall.b2c.service.OrderItemService;
import com.mall.b2c.service.OrderLogService;
import com.mall.b2c.service.OrderService;
import com.mall.b2c.service.ShippingItemService;
import com.mall.b2c.service.ShippingService;
import com.mall.b2c.util.SerialNumberUtil;
import com.mall.common.domain.AreaDomain;
import com.mall.common.exception.NoticeException;
import com.mall.common.service.AreaService;
import com.mall.common.service.impl.BaseServiceImpl;


/**
 * Service实现类 - 发货单
 * @author lzx
 */
@Service("b2cShippingService")
@Transactional(readOnly=true)
public class ShippingServiceImpl extends BaseServiceImpl<ShippingDomain, Long> implements ShippingService {
	
	@Resource
	public void setBaseDao(ShippingDao shippingDao) { 
		super.setBaseDao(shippingDao); 
	}

	@Resource private OrderDao orderDao;
	@Resource private OrderItemDao orderItemDao;
	@Resource private OrderService orderService;
	@Resource private OrderItemService orderItemService;
	@Resource private DeliveryMethodService deliveryMethodService;
	@Resource private DeliveryCenterService deliveryCenterService;
	@Resource private AreaService areaService;
	@Resource private ShippingItemService shippingItemService;
	@Resource private OrderLogService orderLogService;
	
	@Override
	@Transactional(propagation=Propagation.REQUIRED)
	public void shipping(ShippingDomain shipping, Long orderId,
			Long areaId, Long[] orderItemIds, Integer[] quantitys,
			Long deliveryMethodId, Long deliveryCenterId, String operator) {
		OrderDomain order = orderService.find(orderId);
		if(order == null){
			throw new NoticeException("订单不存在");
		}
		orderDao.lock(order, LockModeType.PESSIMISTIC_WRITE);
		if(order.getOrderStatus() != 
				OrderStatus.waitSellerSendGoods && order.getAllShiped()){
			throw new NoticeException("当前订单状态不能进行发货操作");
		}
		//配送方式
		DeliveryMethodDomain deliveryMethod = deliveryMethodService.find(deliveryMethodId);
		if(deliveryMethod == null){
			throw new NoticeException("配送方式不存在");
		}
		//发货点
		DeliveryCenterDomain deliveryCenter = deliveryCenterService.find(deliveryCenterId);
		if(deliveryCenter == null){
			throw new NoticeException("发货点不存在");
		}
		//发货地区
		AreaDomain area = areaService.find(areaId);
		if(area == null){
			throw new NoticeException("发货地区不存在");
		}
		
		shipping.setSendSn(SerialNumberUtil.buildShippingSn());
		shipping.setOrder(order);
		shipping.setArea(area);
		shipping.setDeliveryMethodName(deliveryMethod.getName());
		shipping.setDistrict(area.getFull_name());
		shipping.setOperator(operator);
		this.persist(shipping);
	
		//发货项
		boolean notQuantityErorr = false;
		for(int i = 0; i < orderItemIds.length; i++){
			if(quantitys[i] > 0){
				OrderItemDomain orderItem = orderItemService.find(orderItemIds[i]);
				if(orderItem == null){
					throw new NoticeException("订单项不存在");
				}
				Integer shippedQuantity = orderItem.getShippedQuantity();
				orderItemDao.lock(orderItem, LockModeType.PESSIMISTIC_WRITE);
				if(quantitys[i] > orderItem.getQuantity() - shippedQuantity){
					throw new NoticeException("订单发货数量不正确");
				}
				
				orderItem.setShippedQuantity(shippedQuantity + quantitys[i]);
				orderItemService.update(orderItem);
				
				ShippingItemDomain shippingItem = new ShippingItemDomain();
				shippingItem.setBatch(orderItem.getBatch());
				shippingItem.setOrderItem(orderItem);
				shippingItem.setQuantity(quantitys[i]);
				shippingItem.setProductName(orderItem.getProductName());
				shippingItem.setProductSn(orderItem.getProductCode());
				shippingItem.setShipping(shipping);
				shippingItemService.persist(shippingItem);
				notQuantityErorr = true;
			}
		}
		
		//所有订单项发货数量小于或者等于0
		if(!notQuantityErorr){
			throw new NoticeException("订单发货数量不正确");
		}
		
		order.setShipStatus(ShipStatus.send);
//		order.setLogisticsNo(shipping.getLogisticsNo()); //TODO 若一个订单可多次发货，订单物流单号？？？
		order.setOrderStatus(OrderStatus.waitBuyerConfirmGoods);
		orderService.update(order);
		
		OrderLogDomain log = new OrderLogDomain();
		log.setLogText("订单发货");
		log.setLogType(LogType.ship);
		log.setOperator(operator);
		log.setOperatorType("系统");
		log.setOrder(order);
		orderLogService.persist(log);
	}

}
